package com.fengke.portal.action.weixin;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.parsers.ParserConfigurationException;

import net.sf.json.JSONObject;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import com.fengke.dao.model.MemberModel.Gender;
import com.fengke.dao.model.OrderItemModel;
import com.fengke.dao.model.OrderModel;
import com.fengke.dao.model.OrderModel.OrderStatus;
import com.fengke.dao.model.OrderModel.PaymentStatus;
import com.fengke.dao.model.PaymentModel;
import com.fengke.dao.model.ProductModel;
import com.fengke.dao.model.SystemParam;
import com.fengke.payment.alipay.config.AlipayConfig;
import com.fengke.payment.alipay.util.AlipaySubmit;
import com.fengke.payment.alipay.util.UtilDate;
import com.fengke.payment.tencent.WXPay;
import com.fengke.payment.tencent.common.Configure;
import com.fengke.payment.tencent.common.EncoderHandler;
import com.fengke.payment.tencent.common.RandomStringGenerator;
import com.fengke.payment.tencent.common.Signature;
import com.fengke.payment.tencent.common.XMLParser;
import com.fengke.payment.tencent.protocol.unified_order_protocol.UnifiedOrderReqData;
import com.fengke.portal.action.BaseAction;
import com.fengke.portal.action.portal.PortalAction;
import com.fengke.service.DivisionService;
import com.fengke.service.OrderService;
import com.fengke.service.ProductService;
import com.fengke.service.SystemParamService;
import com.fengke.service.vo.DepartureVO;
import com.fengke.service.vo.DestinationVO;
import com.fengke.service.vo.MemberVO;
import com.fengke.service.vo.OrderVO;
import com.fengke.service.vo.PaymentVO;
import com.fengke.service.vo.ProductCategoryVO;
import com.fengke.service.vo.ProductVO;
import com.fengke.util.Constants;
import com.fengke.util.DateUtil;
import com.fengke.util.LoggerFactory;
import com.fengke.util.StringUtil;

public class WeixinAction extends BaseAction {
	private static final long serialVersionUID = -4608751764426312458L;
	private Logger logger = LoggerFactory.getLogger(PortalAction.class);
	private ProductService productService;
	private DivisionService divisionService;
	private OrderService orderService;
	private SystemParamService systemParamService;
	private ProductVO productVO = new ProductVO();
	private OrderVO orderVO = new OrderVO();
	private PaymentVO paymentVO = new PaymentVO();
	private List<ProductVO> productVOList = new ArrayList<ProductVO>();
	private List<DepartureVO> departureVOList = new ArrayList<DepartureVO>();
	private List<DestinationVO> destinationVOList = new ArrayList<DestinationVO>();
	private List<ProductCategoryVO> productCategoryVOList = new ArrayList<ProductCategoryVO>();
	private List<String> dateList =  new ArrayList<String>(); // 何时
	private Map<String, Object> wxPayParamMap = new TreeMap<String, Object>();
	private String aliPayHTMLText;
	private MemberVO memberVO = new MemberVO();
	private String result;
	private BigDecimal bigDecimalResult;
	
	public String weixinCheck() {
		String signature = this.getRequest().getParameter("signature");
		String timestamp = this.getRequest().getParameter("timestamp");
		String nonce = this.getRequest().getParameter("nonce");
		String echostr = this.getRequest().getParameter("echostr");
		
		if(checkSignature(signature, Configure.getToken(), timestamp, nonce)) {
			result = echostr;
		} else {
			result = "error";
		}
		
		try {
			getResponse().getWriter().print(result);
		} catch (IOException e) {
			logger.error("weixinCheck response.writer.print Exception!", e);
		} finally {
			try {
				getResponse().getWriter().close();
			} catch (IOException e) {
				logger.error("weixinCheck getResponse().getWriter().close() Exception!", e);
			}
		}
		
		return null;
	}
	
	private boolean checkSignature(String signature, String token, String timestamp, String nonce) {
		String[] arr = new String[]{token, timestamp, nonce};
		Arrays.sort(arr);
		StringBuffer content = new StringBuffer();
		for(int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		return signature.equals(EncoderHandler.encode("SHA1", content.toString()));
	}

	public String jsapiSignature() {
		String noncestr = this.getRequest().getParameter("noncestr");
		String timestamp = this.getRequest().getParameter("timestamp");
		String url = this.getRequest().getParameter("url");
		
		SystemParam jsapiTicket = new SystemParam();
		jsapiTicket.setType(SystemParam.ParamType.jsapi_ticket);
		try {
			jsapiTicket = systemParamService.researchSystemParamByType(jsapiTicket);
		} catch (Exception e) {
			logger.error("researchSystemParamByType Exception !jsapiTicket=" + jsapiTicket, e);
		}
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("jsapi_ticket", jsapiTicket.getParamValue());
		paramMap.put("noncestr", noncestr);
		paramMap.put("timestamp", timestamp);
		paramMap.put("url", url);
		
		logger.info("jsapiSignature paramMap=" + paramMap);

		// 将数据存储在map里，再转换成json类型数据，也可以自己手动构造json类型数据
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("data", Signature.getSHA1Sign(paramMap));
		map.put("appId", Configure.getAppid());
		logger.info("jsapiSignature map=" + map);
		JSONObject json = JSONObject.fromObject(map);// 将map对象转换成json类型数据
		result = json.toString();// 给result赋值，传递给页面

		return Constants.ActionReturnName.SUCCESS;
	}

	/**
	 * 获取微信首页列表
	 * 1、产品列表
	 * 2、出发地列表
	 * 3、目的地列表
	 * 4、产品分类列表
	 * 
	 * @return
	 */
	public String index() {
		logger.debug("index method...");
		if(productVO == null) {
			productVO = new ProductVO();
		}
		if(productVO.getProductModel() == null) {
			productVO.setProductModel(new ProductModel());
		}
		productVO.getProductModel().setIsMarketable(true);
		productVO.getProductModel().setExpire(DateUtil.getCurrentDate());
		
		if(getPageBean().getCurrentPage() == null || getPageBean().getCurrentPage() <= 0) {
			getPageBean().setCurrentPage(1);
		}
		
		getPageBean().setPageSize(Constants.PageSize.ESTORE_PAGE_SIZE);
		
		// 获取总量
		Integer productVOListSize = null;
		try {
			productVOListSize = productService.researchProductListSize(productVO);
		} catch (Exception e) {
			logger.error("检索商品总量失败！productVO=" + productVO, e);
		}
		
		if(productVOListSize != null && productVOListSize > 0) {
			getPageBean().setResultItemCount(productVOListSize);
			try {
				productVOList = productService.researchProductList(productVO, (getPageBean().getCurrentPage() - 1) * getPageBean().getPageSize(), getPageBean().getPageSize());
			} catch (Exception e) {
				logger.error("检索商品失败！productVO=" + productVO, e);
			}
		} else {
			getPageBean().setResultItemCount(0);
		}
		/****
		// 获取商品类型列表
		ProductCategoryVO productCategoryVO = new ProductCategoryVO();
		try {
			productCategoryVOList = productService.researchProductCategoryList(productCategoryVO, 0, Integer.MAX_VALUE);
		} catch (Exception e) {
			logger.error("getValidProductCategoryVOList 获取商品类型列表异常！", e);
		}
		// 获取出发地列表
		DepartureVO departureVO = new DepartureVO();
		try {
			departureVOList = divisionService.researchDepartureVOList(departureVO, 0, Integer.MAX_VALUE);
		} catch (Exception e) {
			logger.error("getValidProductCategoryVOList 获取出发地列表异常！", e);
		}
		// 获取目的地列表
		DestinationVO destinationVO = new DestinationVO();
		try {
			destinationVOList = divisionService.researchDestinationVOList(destinationVO, 0, Integer.MAX_VALUE);
		} catch (Exception e) {
			logger.error("getValidDestinationVOList 获取目的地列表异常！", e);
		}
		// 何时
		dateList = getDates();
		****/
		
		// 根据在线产品信息获取商品类型
		try {
			productCategoryVOList = productService.researchProductCategoryListByOnlineProduct(productVO);
		} catch (Exception e) {
			logger.error("researchProductCategoryListByOnlineProduct 获取商品类型列表异常！productVO=" + productVO, e);
		}
		// 根据在线产品信息获取出发地列表
		try {
			departureVOList = productService.researchDepartureVOListByOnlineProduct(productVO);
		} catch (Exception e) {
			logger.error("researchDepartureVOListByOnlineProduct 获取出发地列表异常！productVO=" + productVO, e);
		}
		// 根据在线产品信息获取目的地列表
		try {
			destinationVOList = productService.researchDestinationVOListByOnlineProduct(productVO);
		} catch (Exception e) {
			logger.error("researchDestinationVOListByOnlineProduct 获取目的地列表异常！productVO=" + productVO, e);
		}
		// 何时
		List<String> startDateStrs = null;
		try {
			startDateStrs = productService.researchStartDateListByOnlineProduct(productVO);
			dateList = getDates(startDateStrs);
			String[] dates = (String[]) dateList.toArray(new String[dateList.size()]);
			if(dates != null) {
				Arrays.sort(dates);
				dateList = Arrays.asList(dates);
			}
		} catch (Exception e) {
			logger.error("researchStartDateListByOnlineProduct Exception ! productVO=" + productVO, e);
		}
		
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 首页ajax请求产品列表
	 * 
	 * @return
	 */
	public String ajaxProduct() {
		if(productVO == null) {
			productVO = new ProductVO();
		}
		if(productVO.getProductModel() == null) {
			productVO.setProductModel(new ProductModel());
		}
		productVO.getProductModel().setIsMarketable(true);
		productVO.getProductModel().setExpire(DateUtil.getCurrentDate());
		
		// 主题 categorys
		String categoryStr = this.getRequest().getParameter("categorys");
		if(!StringUtil.isEmpty(categoryStr)) {
			String[] categorys = categoryStr.split(",");
			productVO.getProductModel().setSearchCategoryList(Arrays.asList(categorys));
		}
		// 从哪 origins
		String originStr = this.getRequest().getParameter("origins");
		if(!StringUtil.isEmpty(originStr)) {
			String[] origins = originStr.split(",");
			productVO.getProductModel().setSearchStartAddressList(Arrays.asList(origins));
		}
		// 去哪 dests
		String destStr = this.getRequest().getParameter("dests");
		if(!StringUtil.isEmpty(destStr)) {
			String[] dests = destStr.split(",");
			productVO.getProductModel().setSearchDestinationList(Arrays.asList(dests));
		}
		// 何时 starts
		String startStr = this.getRequest().getParameter("starts");
		if(!StringUtil.isEmpty(startStr)) {
			String[] starts = startStr.split(",");
			productVO.getProductModel().setSearchStartDateList(Arrays.asList(starts));
		}
		
		if(getPageBean().getCurrentPage() == null || getPageBean().getCurrentPage() <= 0) {
			getPageBean().setCurrentPage(1);
		}
		getPageBean().setPageSize(Constants.PageSize.ESTORE_PAGE_SIZE);
		
		// 获取总量
		Integer productVOListSize = null;
		try {
			productVOListSize = productService.researchProductListSize(productVO);
		} catch (Exception e) {
			logger.error("检索商品总量失败！productVO=" + productVO, e);
		}
		
		if(productVOListSize != null && productVOListSize > 0) {
			getPageBean().setResultItemCount(productVOListSize);
			try {
				productVOList = productService.researchProductList(productVO, (getPageBean().getCurrentPage() - 1) * getPageBean().getPageSize(), getPageBean().getPageSize());
			} catch (Exception e) {
				logger.error("检索商品失败！productVO=" + productVO, e);
			}
		} else {
			getPageBean().setResultItemCount(0);
		}
		
		return Constants.ActionReturnName.SUCCESS;
	}
	
	public String ajaxProductMember() {
		if(productVO == null || productVO.getProductModel() == null || productVO.getProductModel().getId() == null) {
			return Constants.ActionReturnName.SUCCESS;
		}
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			logger.error("ajaxProductMember researchProductById Exception! productVO=" + productVO, e);
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	
	/**
	 * 商品详情页
	 * 
	 * @return
	 */
	public String productDetail() {
		if(productVO == null || productVO.getProductModel() == null || productVO.getProductModel().getId() == null) {
			this.addPageDangerMessage("产品编码为空！");
			return INPUT;
		}
		
		Long productId = productVO.getProductModel().getId();
		if(productId == 1777) {
			productVO.getProductModel().setId(1072l);
		}
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			this.logger.error("productDetail 检索商品异常！productId=" + productId, e);
		}
		
		if(ProductModel.ProductType.Merchandise.equals(productVO.getProductModel().getProductType())) {
		} else if(ProductModel.ProductType.Activities.equals(productVO.getProductModel().getProductType())) {
			return "productDetailAC";
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	
	/**
	 * 进入创建订单页面
	 * 
	 * @return
	 */
	public String preCreateOrder() {
		if(productVO == null || productVO.getProductModel() == null || productVO.getProductModel().getId() == null) {
			this.addPageDangerMessage("产品编码为空！");
			return INPUT;
		}
		Long productId = productVO.getProductModel().getId();
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			this.logger.error("productDetail 检索商品异常！productId=" + productId, e);
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 重新下单
	 */
	public String updateOrder() {
		if(productVO == null || productVO.getProductModel() == null || productVO.getProductModel().getId() == null) {
			this.addPageDangerMessage("产品编码为空！");
			return INPUT;
		}
		Long productId = productVO.getProductModel().getId();
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			this.logger.error("updateOrder 检索商品异常！productId=" + productId, e);
		}
		if(orderVO != null && orderVO.getOrderModel() != null && orderVO.getOrderModel().getId() != null) {
			Long orderId = orderVO.getOrderModel().getId();
			try {
				orderVO = orderService.researchOrderById(orderVO);
			} catch (Exception e) {
				this.logger.error("updateOrder 检索Order异常！orderId=" + orderId, e);
			}
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 生成拜仁订单
	 * @return
	 */
	public String createConfirmedOrder() {
		Long input_productId = Long.parseLong(this.getRequest().getParameter("input_productId"));
		BigDecimal input_productPrice = new BigDecimal(this.getRequest().getParameter("input_productPrice"));
		String input_phoneName = this.getRequest().getParameter("input_phoneName");
		String input_gender = this.getRequest().getParameter("input_gender");
		String input_phone = this.getRequest().getParameter("input_phone");
		String input_email = this.getRequest().getParameter("input_email");
		String input_paymentType = this.getRequest().getParameter("input_paymentType");
		String input_startingDate = this.getRequest().getParameter("input_startingDate");
		String input_address = this.getRequest().getParameter("input_address");
		productVO = new ProductVO();
		productVO.setProductModel(new ProductModel());
		productVO.getProductModel().setId(input_productId);
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder researchProductById Exception! productVO=" + productVO, e);
		}
		memberVO = (MemberVO) this.getRequest().getSession().getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
		orderVO = new OrderVO();
		orderVO.setOrderModel(new OrderModel());
		orderVO.getOrderModel().setMember(memberVO.getMemberModel());
		orderVO.getOrderModel().setProductName(productVO.getProductModel().getName());
		if(productVO.getProductModel().getAdminModel() != null) {
			orderVO.getOrderModel().setAdminId(productVO.getProductModel().getAdminModel().getId());
		}
		orderVO.getOrderModel().setGoDate(DateUtil.parseDate(input_startingDate));
		orderVO.getOrderModel().setOrderStatus(OrderStatus.unconfirmed);
		orderVO.getOrderModel().setPaymentStatus(PaymentStatus.unpaid);
		orderVO.getOrderModel().setExpire(DateUtils.addMinutes(new Date(), 45));
		orderVO.getOrderModel().setAdultNum(1l);
		orderVO.getOrderModel().setChildrenNum(0l);
		orderVO.getOrderModel().setIsShareHouse(false);
		orderVO.getOrderModel().setPhoneName(input_phoneName);
		orderVO.getOrderModel().setAddress(input_address);
		if("male".equals(input_gender)) {
			orderVO.getOrderModel().setGender(Gender.male);
		} else {
			orderVO.getOrderModel().setGender(Gender.female);
		}
		orderVO.getOrderModel().setPhone(input_phone);
		orderVO.getOrderModel().setEmail(input_email);
		orderVO.getOrderModel().setCreateDate(new Date());
		orderVO.getOrderModel().setModifyDate(new Date());
		orderVO.getOrderModel().setIsEffective(true);
		orderVO.getOrderModel().setIsAssociateShow(false);
		
		List<OrderItemModel> orderItems = new ArrayList<OrderItemModel>();
		OrderItemModel orderItem = new OrderItemModel();
		orderItem.setCreateDate(new Date());
		orderItem.setModifyDate(new Date());
		orderItem.setPrice(input_productPrice);
		orderItem.setQuantity(1);
		orderItem.setFullName(productVO.getProductModel().getName());
		orderItem.setName(productVO.getProductModel().getName());
		orderItem.setProduct(productVO.getProductModel());
		orderItem.setGender(orderVO.getOrderModel().getGender());
		orderItem.setMemberName(input_phoneName);
		orderItem.setIsAdult(true);
		orderItems.add(orderItem);
		orderVO.setOrderItemModelList(orderItems);
		
		try {
			orderVO = orderService.createOrder(orderVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder createOrder Exception! orderVO=" + orderVO, e);
		}
		
		// 创建支付单
		paymentVO = new PaymentVO();
		paymentVO.setPaymentModel(new PaymentModel());
		paymentVO.getPaymentModel().setType(PaymentModel.Type.payment);
		paymentVO.getPaymentModel().setMethod(PaymentModel.Method.online);
		paymentVO.getPaymentModel().setStatus(PaymentModel.Status.wait);
		paymentVO.getPaymentModel().setAdminModel(productVO.getProductModel().getAdminModel());
		paymentVO.getPaymentModel().setSubject(productVO.getProductModel().getName());
		if("weixin".equals(input_paymentType)) {
			paymentVO.getPaymentModel().setPaymentMethod("微信支付");
		} else if("ali".equals(input_paymentType)) {
			paymentVO.getPaymentModel().setPaymentMethod("支付宝支付");
		}
		paymentVO.getPaymentModel().setFee(new BigDecimal(0l));
		paymentVO.getPaymentModel().setAmount(orderVO.getAmount());
		paymentVO.getPaymentModel().setPaymentPluginId(input_paymentType);
		paymentVO.getPaymentModel().setExpire(DateUtils.addMinutes(new Date(), 45));
		paymentVO.getPaymentModel().setOrder(orderVO.getOrderModel());
		paymentVO.getPaymentModel().setCreateDate(new Date());
		paymentVO.getPaymentModel().setModifyDate(new Date());
		try {
			paymentVO = orderService.createPayment(paymentVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder createPayment Exception! paymentVO=" + paymentVO, e);
		}
		if("ali".equals(input_paymentType)) {
			aliPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "aliPayment";
		} else if("weixin".equals(input_paymentType)) {
			weixinPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "weixinPayment";
		}
		this.addPageDangerMessage("异常！！！！！！！！！！！！！！！！！！");
		return Constants.ActionReturnName.ERROR;
	}
	
	public String createOrder() {
		preCreateMemberOrder();
		if(this.hasPageDangerMessage()) {
			return Constants.ActionReturnName.ERROR;
		}
		String param_goDateString = this.getRequest().getParameter("param_goDateString");
		String param_paymentType = this.getRequest().getParameter("param_paymentType");
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder researchProductById Exception! productVO=" + productVO, e);
		}
		memberVO = (MemberVO) this.getRequest().getSession().getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
		orderVO.getOrderModel().setGoDate(DateUtil.parseDate(param_goDateString));
		orderVO.getOrderModel().setMember(memberVO.getMemberModel());
		orderVO.getOrderModel().setProductName(productVO.getProductModel().getName());
		if(productVO.getProductModel().getAdminModel() != null) {
			orderVO.getOrderModel().setAdminId(productVO.getProductModel().getAdminModel().getId());
		}
		orderVO.getOrderModel().setOrderStatus(OrderStatus.unconfirmed);
		orderVO.getOrderModel().setPaymentStatus(PaymentStatus.unpaid);
		orderVO.getOrderModel().setExpire(DateUtils.addMinutes(new Date(), 45));
		orderVO.getOrderModel().setCreateDate(new Date());
		orderVO.getOrderModel().setModifyDate(new Date());
		orderVO.getOrderModel().setIsEffective(true);
		orderVO.getOrderModel().setIsAssociateShow(false);
		
		List<OrderItemModel> orderItemList = new ArrayList<OrderItemModel>(); //orderVO.getOrderItemModelList();
		OrderItemModel orderItemModel = new OrderItemModel();
		orderItemModel.setCreateDate(new Date());
		orderItemModel.setModifyDate(new Date());
		orderItemModel.setPrice(productVO.getProductModel().getPrice());
		orderItemModel.setQuantity(1);
		orderItemModel.setFullName(productVO.getProductModel().getName());
		orderItemModel.setName(productVO.getProductModel().getName());
		orderItemModel.setProduct(productVO.getProductModel());
		orderItemModel.setGender(orderVO.getOrderModel().getGender());
		orderItemModel.setMemberName(orderVO.getOrderModel().getPhoneName());
		orderItemModel.setIsAdult(true);
		orderItemList.add(0, orderItemModel);
		
		if(orderVO.getOrderItemModelList() != null && orderVO.getOrderItemModelList().size() > 0) {
			for(int i = 0; i < orderVO.getOrderItemModelList().size(); i ++) {
				OrderItemModel item = orderVO.getOrderItemModelList().get(i);
				if(item != null && !StringUtil.isEmpty(item.getMemberName())) {
					item.setCreateDate(new Date());
					item.setModifyDate(new Date());
					item.setQuantity(1);
					item.setFullName(productVO.getProductModel().getName());
					item.setName(productVO.getProductModel().getName());
					item.setProduct(productVO.getProductModel());
					if(item.getIsAdult() != null && item.getIsAdult()) {
						item.setPrice(productVO.getProductModel().getPrice());
					} else {
						item.setPrice(productVO.getProductModel().getChildrenPrice());
					}
					orderItemList.add(item);
				}
			}
		}
		orderVO.setOrderItemModelList(orderItemList);
		
		try {
			orderVO = orderService.createOrder(orderVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder createOrder Exception! orderVO=" + orderVO, e);
		}
		if(orderVO == null) {
			this.addPageDangerMessage("订单创建失败！");
			return Constants.ActionReturnName.ERROR;
		}
		
		// 创建支付单
		paymentVO = new PaymentVO();
		paymentVO.setPaymentModel(new PaymentModel());
		paymentVO.getPaymentModel().setType(PaymentModel.Type.payment);
		paymentVO.getPaymentModel().setMethod(PaymentModel.Method.online);
		paymentVO.getPaymentModel().setStatus(PaymentModel.Status.wait);
		paymentVO.getPaymentModel().setAdminModel(productVO.getProductModel().getAdminModel());
		paymentVO.getPaymentModel().setSubject(productVO.getProductModel().getName());
		if("weixin".equals(param_paymentType)) {
			paymentVO.getPaymentModel().setPaymentMethod("微信支付");
		} else if("ali".equals(param_paymentType)) {
			paymentVO.getPaymentModel().setPaymentMethod("支付宝支付");
		}
		paymentVO.getPaymentModel().setFee(new BigDecimal(0l));
		paymentVO.getPaymentModel().setAmount(orderVO.getAmount());
		paymentVO.getPaymentModel().setPaymentPluginId(param_paymentType);
		paymentVO.getPaymentModel().setExpire(DateUtils.addMinutes(new Date(), 45));
		paymentVO.getPaymentModel().setOrder(orderVO.getOrderModel());
		paymentVO.getPaymentModel().setCreateDate(new Date());
		paymentVO.getPaymentModel().setModifyDate(new Date());
		try {
			paymentVO = orderService.createPayment(paymentVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder createPayment Exception! paymentVO=" + paymentVO, e);
		}
		if(paymentVO == null) {
			this.addPageDangerMessage("支付单创建失败！");
			return Constants.ActionReturnName.ERROR;
		}
		if("ali".equals(param_paymentType)) {
			aliPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "aliPayment";
		} else if("weixin".equals(param_paymentType)) {
			weixinPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "weixinPayment";
		}
		this.addPageDangerMessage("异常！！！！！！！！！！！！！！！！！！");
		return Constants.ActionReturnName.ERROR;
	}
	/**
	 * 我的订单，去付款
	 * 
	 * @return
	 */
	public String payOrderAmount() {
		// 根据订单信息，找到paymentId
		memberVO = (MemberVO) this.getRequest().getSession().getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
		if(orderVO == null || orderVO.getOrderModel() == null || orderVO.getOrderModel().getId() == null) {
			this.addPageDangerMessage("订单信息不能为空！");
			return Constants.ActionReturnName.ERROR;
		}
		
		try {
			orderVO = orderService.researchOrderById(orderVO);
		} catch (Exception e) {
			logger.error("payOrderAmount researchOrderById Exception! orderVO=" + orderVO, e);
		}
		if(orderVO == null) {
			this.addPageDangerMessage("根据订单号检索不到订单信息！");
			return Constants.ActionReturnName.ERROR;
		}
		paymentVO = new PaymentVO();
		paymentVO.setPaymentModel(new PaymentModel());
		paymentVO.getPaymentModel().setOrder(orderVO.getOrderModel());
		try {
			paymentVO = orderService.researchPaymentVOById(paymentVO);
		} catch (Exception e) {
			logger.error("payOrderAmount researchPaymentVOById Exception! paymentVO=" + paymentVO, e);
		}
		
		if(paymentVO == null) {
			this.addPageDangerMessage("支付信息不存在！");
			logger.error("支付信息不存在！paymentVO=" + paymentVO);
			return Constants.ActionReturnName.ERROR;
		}
		
		String param_paymentType = paymentVO.getPaymentModel().getPaymentPluginId();
		if("ali".equals(param_paymentType)) {
			aliPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "aliPayment";
		} else if("weixin".equals(param_paymentType)) {
			weixinPayAPI();
			if(this.hasPageDangerMessage()) {
				return Constants.ActionReturnName.ERROR;
			}
			return "weixinPayment";
		}
		this.addPageDangerMessage("异常！！！！！！！！！！！！！！！！！！");
		return Constants.ActionReturnName.ERROR;
	}
	
	private void preCreateMemberOrder() {
		if(productVO == null || productVO.getProductModel() == null || productVO.getProductModel().getId() == null) {
			this.addPageDangerMessage("资源信息缺失");
			return;
		}
		if(orderVO == null || orderVO.getOrderModel() == null) {
			this.addPageDangerMessage("订单信息缺失");
			return;
		}
		String input_paymentType = this.getRequest().getParameter("param_paymentType");
		if(StringUtil.isEmpty(input_paymentType)) {
			this.addPageDangerMessage("支付方式不能为空！");
		}
		String param_goDateString = this.getRequest().getParameter("param_goDateString");
		
		if(StringUtil.isEmpty(param_goDateString)) {
			this.addPageDangerMessage("出发日期不能为空！");
		}
		if(orderVO.getOrderModel().getAdultNum() == null || orderVO.getOrderModel().getAdultNum() < 1) {
			this.addPageDangerMessage("成人数目不合法！");
		}
		if(orderVO.getOrderModel().getAdultNum() == null) {
			this.addPageDangerMessage("儿童数目不合法！");
		}
	}
	
	private void aliPayAPI() {
		//请求业务参数详细
		StringBuilder reqDataTokenBuilder = new StringBuilder();
		reqDataTokenBuilder.append("<direct_trade_create_req>")
				 .append("<notify_url>").append(AlipayConfig.notify_url).append("</notify_url>")
				 .append("<call_back_url>").append(AlipayConfig.call_back_url).append("</call_back_url>")
				 .append("<seller_account_name>").append(AlipayConfig.seller_email).append("</seller_account_name>")
				 .append("<out_trade_no>").append(orderVO.getOrderModel().getSn()).append("</out_trade_no>")
				 .append("<subject>").append(paymentVO.getPaymentModel().getSubject()).append("</subject>")
				 .append("<total_fee>").append(orderVO.getAmount()).append("</total_fee>")
				 .append("<merchant_url>").append(AlipayConfig.merchant_url).append("</merchant_url>")
				 .append("</direct_trade_create_req>");
		//把请求参数打包成数组
		Map<String, String> sParaTempToken = new HashMap<String, String>();
		sParaTempToken.put("service", "alipay.wap.trade.create.direct");
		sParaTempToken.put("partner", AlipayConfig.partner);
		sParaTempToken.put("_input_charset", AlipayConfig.input_charset);
		sParaTempToken.put("sec_id", AlipayConfig.sign_type);
		sParaTempToken.put("format", AlipayConfig.format);
		sParaTempToken.put("v", AlipayConfig.v);
		//请求号 必填，须保证每次请求都是唯一
		sParaTempToken.put("req_id", UtilDate.getOrderNum());
		sParaTempToken.put("req_data", reqDataTokenBuilder.toString());
		logger.info("AliPay API!..! sParaTempToken=" + sParaTempToken);
		//建立请求
		String sHtmlTextToken = null;
		try {
			sHtmlTextToken = AlipaySubmit.buildRequest(AlipayConfig.ALIPAY_GATEWAY_NEW,"", "",sParaTempToken);
		} catch (Exception e) {
			logger.error("aliPayAPI AlipaySubmit.buildRequest Exception! sParaTempToken=" + sParaTempToken, e);
		}
		if(!StringUtil.isEmpty(sHtmlTextToken)) {
			//URLDECODE返回的信息
			try {
				sHtmlTextToken = URLDecoder.decode(sHtmlTextToken,AlipayConfig.input_charset);
			} catch (UnsupportedEncodingException e) {
				logger.error("aliPayAPI URLDecoder.decode Exception! sHtmlTextToken=" + sHtmlTextToken, e);
			}
			if(!StringUtil.isEmpty(sHtmlTextToken)) {
				//获取token
				String request_token = null;
				try {
					request_token = AlipaySubmit.getRequestToken(sHtmlTextToken);
				} catch (Exception e) {
					logger.error("aliPayAPI AlipaySubmit.getRequestToken Exception! sHtmlTextToken=" + sHtmlTextToken, e);
				}
				//out.println(request_token);
				if(!StringUtil.isEmpty(request_token)) {
					////////////////////////////////////根据授权码token调用交易接口alipay.wap.auth.authAndExecute//////////////////////////////////////
					//业务详细
					StringBuilder reqDataBuilder = new StringBuilder();
					reqDataBuilder.append("<auth_and_execute_req>")
					.append("<request_token>").append(request_token).append("</request_token>")
					.append("</auth_and_execute_req>");
					//把请求参数打包成数组
					Map<String, String> sParaTemp = new HashMap<String, String>();
					sParaTemp.put("service", "alipay.wap.auth.authAndExecute");
					sParaTemp.put("partner", AlipayConfig.partner);
					sParaTemp.put("_input_charset", AlipayConfig.input_charset);
					sParaTemp.put("sec_id", AlipayConfig.sign_type);
					sParaTemp.put("format", AlipayConfig.format);
					sParaTemp.put("v", AlipayConfig.v);
					sParaTemp.put("req_data", reqDataBuilder.toString());
					
					logger.info("AliPay API!..! sParaTemp=" + sParaTemp);
					//建立请求
					aliPayHTMLText = AlipaySubmit.buildRequest(AlipayConfig.ALIPAY_GATEWAY_NEW, sParaTemp, "get", "确认");
					if(StringUtil.isEmpty(aliPayHTMLText)) {
						logger.error("支付宝支付建立请求异常！sParaTemp=" + sParaTemp);
						this.addPageDangerMessage("支付宝支付建立请求异常！");
					}
					logger.info("AliPay API!..! aliPayHTMLText=" + aliPayHTMLText);
				} else {
					logger.error("支付宝支付获取token异常！sHtmlTextToken=" + sHtmlTextToken);
					this.addPageDangerMessage("支付宝支付获取token异常！");
				}
			} else {
				logger.error("支付宝支付URLDecoder异常！sHtmlTextToken=" + sHtmlTextToken);
				this.addPageDangerMessage("支付宝支付URLDecoder异常！");
			}
		} else {
			logger.error("支付宝支付首次建立请求异常！sParaTempToken=" + sParaTempToken);
			this.addPageDangerMessage("支付宝支付首次建立请求异常！");
		}
	}

	private void weixinPayAPI() {
		String result = null;
		try {
			//input_productPrice.multiply(new BigDecimal(100)).longValue()
			result = WXPay.requestUnifiedOrderService(new UnifiedOrderReqData(paymentVO.getPaymentModel().getSubject(), orderVO.getOrderModel().getSn(), orderVO.getAmount().multiply(new BigDecimal(100)).longValue(), memberVO.getMemberModel().getOpenId()));
		} catch (Exception e) {
			logger.error("createConfirmedOrder requestUnifiedOrderService Exception", e);
		}
		if(result != null) {
			boolean signCheck = false;
			try {
				signCheck = Signature.checkIsSignValidFromResponseString(result);
			} catch (ParserConfigurationException e) {
				logger.error("createConfirmedOrder ParserConfigurationException Exception! result=" + result, e);
			} catch (IOException e) {
				logger.error("createConfirmedOrder IOException Exception! result=" + result, e);
			} catch (SAXException e) {
				logger.error("createConfirmedOrder SAXException Exception! result=" + result, e);
			}
			if(signCheck) {
				Map<String, Object> resultParam = null;
				try {
					resultParam = XMLParser.getMapFromXML(result);
				} catch (ParserConfigurationException e) {
					logger.error("createConfirmedOrder ParserConfigurationException Exception! result=" + result, e);
				} catch (IOException e) {
					logger.error("createConfirmedOrder IOException Exception! result=" + result, e);
				} catch (SAXException e) {
					logger.error("createConfirmedOrder SAXException Exception! result=" + result, e);
				}
				logger.info("resultParam=" + resultParam);
				String prepay_id = resultParam.get("prepay_id") == null ? null : (String)resultParam.get("prepay_id");
				if(prepay_id != null) {
					wxPayParamMap.put("appId", Configure.getAppid());
					wxPayParamMap.put("timeStamp",Configure.getTimeStamp());		
					wxPayParamMap.put("nonceStr",RandomStringGenerator.getRandomStringByLength(Configure.getRandomStringLength()));
					wxPayParamMap.put("package", "prepay_id="+prepay_id);
					wxPayParamMap.put("signType", "MD5");
					String paySign = null;
					paySign = Signature.getSign(wxPayParamMap);
					wxPayParamMap.put("paySign", paySign);	
				} else {
					logger.error("获取 prepay_id Exception!");
					this.addPageDangerMessage("获取 prepay_id Exception!");
				}
			} else {
				logger.error("获取 prepay_id Exception 签名验签失败!");
				this.addPageDangerMessage("获取 prepay_id Exception 签名验签失败!");
			}
		} else {
			logger.error("获取 prepay_id Exception 返回结果为空!");
			this.addPageDangerMessage("获取 prepay_id Exception 签名验签失败!");
		}
	}

	/**
	 * 展现用户信息
	 * 
	 * @return
	 */
	public String showMemberInfo() {
		memberVO = (MemberVO) this.getRequest().getSession().getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
		// 获取各个状态订单
		try {
			memberVO = orderService.researchMemberOrders(memberVO);
		} catch (Exception e) {
			logger.error("researchMemberOrders Exception! memberVO=" + memberVO, e);
		}
		
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 用户订单详情
	 * 
	 * @return
	 */
	public String userOrderDetail() {
		if(orderVO == null || orderVO.getOrderModel() == null || orderVO.getOrderModel().getId() == null) {
			return "input";
		}
		memberVO = (MemberVO) this.getRequest().getSession().getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
		try {
			orderVO = orderService.researchOrderById(orderVO);
		} catch (Exception e) {
			logger.error("userOrderDetail researchOrderById Exception!", e);
		}
		
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 更新订单状态
	 * @return
	 */
	public String changeStatus() {
		if(orderVO == null || orderVO.getOrderModel() == null || orderVO.getOrderModel().getId() == null || orderVO.getOrderModel().getOrderStatus() == null) {
			return Constants.ActionReturnName.SUCCESS;
		}
		try {
			orderService.updateOrderVOStatus(orderVO);
		} catch (Exception e) {
			logger.error("changeStatus updateOrderVOStatus Exception! orderVO=" + orderVO, e);
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 删除订单
	 * @return
	 */
	public String deleteOrder() {
		if(orderVO == null || orderVO.getOrderModel() == null || orderVO.getOrderModel().getId() == null) {
			return Constants.ActionReturnName.SUCCESS;
		}
		List<String> idList = new ArrayList<String>();
		idList.add(String.valueOf(orderVO.getOrderModel().getId()));
		try {
			orderService.deleteOrderByIds(idList);
		} catch (Exception e) {
			logger.error("deleteOrder deleteOrderByIds Exception! idList=" + idList, e);
		}
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 同行人可见
	 * 
	 * @return
	 */
	public String associateShow() {
		if(orderVO == null || orderVO.getOrderModel() == null || orderVO.getOrderModel().getId() == null) {
			return Constants.ActionReturnName.SUCCESS;
		}
		if(orderVO.getOrderModel().getIsAssociateShow() == null) {
			orderVO.getOrderModel().setIsAssociateShow(true);
		}
		try {
			orderService.associateShow(orderVO);
		} catch (Exception e) {
			logger.error("associateShow Exception! orderVO=" + orderVO, e);
		}
		this.setResult("true");
		return Constants.ActionReturnName.SUCCESS;
	}
	/**
	 * 计算订单价格
	 * 
	 * @return
	 */
	public String countPrice() {
		try {
			productVO = productService.researchProductById(productVO);
		} catch (Exception e) {
			logger.error("createConfirmedOrder researchProductById Exception! productVO=" + productVO, e);
		}
		
		String adultNumStr = this.getRequest().getParameter("adultNum");
		String childrenNumStr = this.getRequest().getParameter("childrenNum");
		String isShareHouseStr = this.getRequest().getParameter("isShareHouse");
		int adultNum = 0;
		if(!StringUtil.isEmpty(adultNumStr)) {
			adultNum = Integer.parseInt(adultNumStr);
		}
		int childrenNum = 0;
		if(!StringUtil.isEmpty(childrenNumStr)) {
			childrenNum = Integer.parseInt(childrenNumStr);
		}
		boolean isShareHouse = false;
		if(!StringUtil.isEmpty(isShareHouseStr)) {
			isShareHouse = Boolean.getBoolean(childrenNumStr);
		}
		bigDecimalResult = countOrderPrice(productVO.getProductModel(), adultNum, childrenNum, isShareHouse);
		
		return Constants.ActionReturnName.SUCCESS;
	}
	
	private BigDecimal countOrderPrice(ProductModel product, int adultNum, int childrenNum, boolean isShareHouse) {
		BigDecimal adultAmount=new BigDecimal(0);
    	BigDecimal childrenAmount=new BigDecimal(0);
    	if(isShareHouse){
    		adultAmount=product.getPrice().multiply(new BigDecimal(adultNum));
    		childrenAmount=product.getChildrenPrice().multiply(new BigDecimal(childrenNum));
    	}else{
    		adultAmount=(product.getPrice().add(product.getHoursePrice())).multiply(new BigDecimal(adultNum));
    		childrenAmount=(product.getChildrenPrice().add(product.getHoursePrice())).multiply(new BigDecimal(childrenNum));
    	}
    	return adultAmount.add(childrenAmount);
	}

	private List<String> getDates(List<String> startDateStrs) {
		List<String> dates =  new ArrayList<String>(); 
		if (startDateStrs == null || startDateStrs.size() <= 0) {
			Date now = new Date();
			for(int i = 0 ; i< 12 ; i++){
				dates.add(DateUtil.getYear(DateUtil.addMonth(now, i))+"-"+DateUtil.getMonth(DateUtil.addMonth(now, i)));
			}
		} else {
			Map<String, String> startDateMap = new HashMap<String, String>();
			for(String startDateStr : startDateStrs) {
				if(startDateStr != null) {
					String[] startDates = startDateStr.split(",");
					if(startDates != null) {
						for(int i = 0; i < startDates.length; i ++) {
							startDateMap.put(startDates[i].substring(0, "yyyy-MM".length()), "");
						}
					}
				}
			}
			if(startDateMap.size() > 0) {
				for(String key : startDateMap.keySet()) {
					dates.add(key);
				}
			}
		}
		return dates;
	}
	
	public ProductService getProductService() {
		return productService;
	}
	public void setProductService(ProductService productService) {
		this.productService = productService;
	}
	public OrderService getOrderService() {
		return orderService;
	}
	public void setOrderService(OrderService orderService) {
		this.orderService = orderService;
	}
	public List<ProductVO> getProductVOList() {
		return productVOList;
	}
	public void setProductVOList(List<ProductVO> productVOList) {
		this.productVOList = productVOList;
	}
	public ProductVO getProductVO() {
		return productVO;
	}
	public void setProductVO(ProductVO productVO) {
		this.productVO = productVO;
	}
	public List<DepartureVO> getDepartureVOList() {
		return departureVOList;
	}
	public void setDepartureVOList(List<DepartureVO> departureVOList) {
		this.departureVOList = departureVOList;
	}
	public List<DestinationVO> getDestinationVOList() {
		return destinationVOList;
	}
	public void setDestinationVOList(List<DestinationVO> destinationVOList) {
		this.destinationVOList = destinationVOList;
	}
	public List<ProductCategoryVO> getProductCategoryVOList() {
		return productCategoryVOList;
	}
	public void setProductCategoryVOList(List<ProductCategoryVO> productCategoryVOList) {
		this.productCategoryVOList = productCategoryVOList;
	}
	public DivisionService getDivisionService() {
		return divisionService;
	}
	public void setDivisionService(DivisionService divisionService) {
		this.divisionService = divisionService;
	}

	public List<String> getDateList() {
		return dateList;
	}

	public void setDateList(List<String> dateList) {
		this.dateList = dateList;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public SystemParamService getSystemParamService() {
		return systemParamService;
	}

	public void setSystemParamService(SystemParamService systemParamService) {
		this.systemParamService = systemParamService;
	}

	public OrderVO getOrderVO() {
		return orderVO;
	}

	public void setOrderVO(OrderVO orderVO) {
		this.orderVO = orderVO;
	}

	public PaymentVO getPaymentVO() {
		return paymentVO;
	}

	public void setPaymentVO(PaymentVO paymentVO) {
		this.paymentVO = paymentVO;
	}

	public Map<String, Object> getWxPayParamMap() {
		return wxPayParamMap;
	}

	public void setWxPayParamMap(Map<String, Object> wxPayParamMap) {
		this.wxPayParamMap = wxPayParamMap;
	}

	public MemberVO getMemberVO() {
		return memberVO;
	}

	public void setMemberVO(MemberVO memberVO) {
		this.memberVO = memberVO;
	}

	public String getAliPayHTMLText() {
		return aliPayHTMLText;
	}

	public void setAliPayHTMLText(String aliPayHTMLText) {
		this.aliPayHTMLText = aliPayHTMLText;
	}

	public BigDecimal getBigDecimalResult() {
		return bigDecimalResult;
	}

	public void setBigDecimalResult(BigDecimal bigDecimalResult) {
		this.bigDecimalResult = bigDecimalResult;
	}
}
